﻿using System;

using Microsoft.WowAddonStudio.Lua.Parser;

namespace Microsoft.WowAddonStudio.Lua.Tests.Parser
{
    public struct ParsedToken : IEquatable<ParsedToken>
    {
        private readonly Tokens token;
        private readonly LexLocation lexLocation;

        /// <summary>
        /// Initializes a new instance of the <see cref="ParsedToken"/> struct.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="lexLocation">The lex location.</param>
        public ParsedToken(Tokens token, LexLocation lexLocation)
        {
            this.token = token;
            this.lexLocation = lexLocation;
        }

        /// <summary>
        /// Gets the token parsed.
        /// </summary>
        public Tokens Token
        {
            get { return token; }
        }

        /// <summary>
        /// Gets the location of the parsed token.
        /// </summary>
        public LexLocation LexLocation
        {
            get { return lexLocation; }
        }


        /// <summary>
        /// Returns the hash code for this instance.
        /// </summary>
        /// <returns>
        /// A 32-bit signed integer that is the hash code for this instance.
        /// </returns>
        public override int GetHashCode()
        {
            unchecked
            {
                return (token.GetHashCode() * 397) ^ (lexLocation != null ? lexLocation.GetHashCode() : 0);
            }
        }
        /// <summary>
        /// Indicates whether this instance and a specified object are equal.
        /// </summary>
        /// <param name="obj">Another object to compare to.</param>
        /// <returns>
        /// true if <paramref name="obj"/> and this instance are the same type and represent the same value; otherwise, false.
        /// </returns>
        public override bool Equals(object obj)
        {
            if (obj.GetType() != typeof(ParsedToken))
                return false;
            return Equals((ParsedToken)obj);
        }
        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other">An object to compare with this object.</param>
        /// <returns>
        /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
        /// </returns>
        public bool Equals(ParsedToken other)
        {
            return Equals(other.token, token) && Equals(other.lexLocation, lexLocation);
        }

        /// <summary>
        /// Returns the fully qualified type name of this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"/> containing a fully qualified type name.
        /// </returns>
        public override string ToString()
        {
            return String.Format("{0} [{1}]", Token, LexLocation);
        }
    }
}